import inspect
from django.http import HttpResponseRedirect
from django.http import HttpResponse
from django.shortcuts import render_to_response
from django.template import RequestContext

from tppt.lib import exceptions
from tppt.lib import utils
from tppt.lib.actions.url import get_action_url

getters={}
def register_action_getter(cls, getter, lister, class_getter=False):
	index=(cls, class_getter)
	if index not in getters:
		getters[index]=[]
	getters[index].append((getter, lister))

def get_action(object, name, master_object=-1, getting_class=False):
	if master_object==-1:
		master_object=object
	index=(master_object, getting_class)
	if index in getters:
		getter_list=getters[index]
		for getter in getter_list:
			action=getter[0](object, name)
			if action:
				return action
	if hasattr(master_object, '__bases__'):
		for mo in master_object.__bases__:
			action=get_action(object, name, mo, getting_class)
			if action:
				return action
	elif not getting_class and hasattr(master_object, '__class__'):
		action=get_action(object, name, master_object.__class__, True)
		if action:
			return action
	raise exceptions.MissingActionError(name)

def get_actions(object=None, master_object=-1, getting_class=False):
	if master_object==-1:
		master_object=object
	lst=[]
	index=(master_object, getting_class)
	if index in getters:
		getter_list=getters[index]
		for getter in getter_list:
			new_lst=getter[1](object)
			lst.extend(new_lst)
	if hasattr(master_object, '__bases__'):
		for mo in master_object.__bases__:
			lst.extend(get_actions(object, mo, getting_class))
	elif not getting_class and hasattr(master_object, '__class__'):
		lst.extend(get_actions(object, master_object.__class__, True))
	return lst
	

def get_actions_details(object):
	action_names=get_actions(object)
	res=[]
	for action_name in action_names:
		action=get_action(object, action_name)
		res.append({
			'name': action_name,
			'caption': action.get_caption(),
			'url': action.get_url(),
			'imageUrl': action.get_image_url(),
			})
	return res


class BaseAction(object):
	caption=None
	image_url=None
	def __init__(self, object=None, request=None, **kwargs):
		self.object=object
		self.params=self.get_param_defaults().copy()
		self.params.update(kwargs)
		if request:
			self.assign_request(request)
	def assign_request(self, request):
		self.request=request
	def add_params(self, params):
		utils.update_existing(self.params, params, keep_type=True)


	def get_param_defaults(self):
		return {}
	def get_nondefault_params(self):
		defaults=self.get_param_defaults()
		params=self.params
		res={}
		for p in params:
			if params[p]!=defaults[p]:
				res[p]=params[p]
		return res

	def get_name(self):
		class_name=self.__class__.__name__
		name=utils.camelcase_to_underscore(class_name)
		if name[-7:]=='_action':
			name=name[:-7]
		return name
	def get_caption(self):
		if self.caption:
			return self.caption
		name=self.get_name()
		return name.replace('_', ' ').capitalize()
	def get_url(self, user_params={}):
		return get_action_url(self, self.object, user_params=user_params)
	def get_image_url(self):
		return self.image_url

	def perform(self):
		raise exceptions.NotImplementedError()
class NonvisualAction(BaseAction):
	def perform_nonvisual():
		pass
	def perform(self):
		self.perform_nonvisual()
		
		request=self.request
		if request.META.has_key('HTTP_REFERER'):
			url=request.META['HTTP_REFERER']
		else:
			url='/'
		return HttpResponseRedirect(url)
class TemplateAction(BaseAction):
	template=None
	
	def perform_template(self):
		raise exceptions.NotImplementedError()
		
	def perform(self):
		template=self.template
		res=self.perform_template()
		if isinstance(res, HttpResponse):
			return res
		else:
			return render_to_response(template, res,  RequestContext(self.request))
class GetPostAction(TemplateAction):
	def get_template_params(self):
		return {}
	def is_success(self):
		return True
	def success(self):
		pass
		
	def perform_template(self):
		request=self.request
		if request.method == 'POST' and self.is_success():
			self.success()
			
			if request.POST.has_key('hidden'):
				url=request.POST['hidden']
			elif request.META.has_key('HTTP_REFERER'):
				url=request.META['HTTP_REFERER']
			else:
				url='/'
			return HttpResponseRedirect(url)
		else:
			params=self.get_template_params()
			if request.META.has_key('HTTP_REFERER'):
				params['hidden']=request.META['HTTP_REFERER']
			return params



class RootAction(TemplateAction):
	template='base.html'
	
	def perform_template(self):
		return {}
	
def get_none_actions():
	return ['root']
def get_none_action(name):
	if name == 'root':
		return RootAction()

register_action_getter(None, lambda x, name:get_none_action(name), lambda x:get_none_actions(), False)
